home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ELYVER10.ZIP / MIKXMAS.ZIP / source / mikcvt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-12  |  7.8 KB  |  398 lines

  1. /*
  2.  
  3. Name:
  4. MIKCVT.C
  5.  
  6. Description:
  7. Program to convert any module into a .UNI module
  8.  
  9. Portability:
  10. All systems - all compilers
  11.  
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16.  
  17. #include "wildfile.h"
  18. #include "mikmod.h"
  19.  
  20. /*
  21.     Declare external loaders:
  22.  */
  23.  
  24. extern LOADER load_mtm, load_s3m, load_ult, load_mod, load_uni, load_xm, load_stm, load_m15;
  25.  
  26.  
  27. FILE *fpi, *fpo;
  28.  
  29.  
  30. UWORD numsamples;
  31. ULONG samplepos[128];
  32. ULONG samplesize[128];
  33. UBYTE buf[8000];
  34.  
  35.  
  36. BOOL CopyData(FILE * fpi, FILE * fpo, ULONG len)
  37. {
  38.      ULONG todo;
  39.  
  40.      while (len) {
  41.     todo = (len > 8000) ? 8000 : len;
  42.     if (!fread(buf, todo, 1, fpi))
  43.          return 0;
  44.     fwrite(buf, todo, 1, fpo);
  45.     len -= todo;
  46.      }
  47.      return 1;
  48. }
  49.  
  50.  
  51. /***************************************************************************
  52. ****************************************************************************
  53. ***************************************************************************/
  54.  
  55.  
  56. BOOL TrkCmp(UBYTE * t1, UBYTE * t2)
  57. {
  58.     UWORD l1, l2;
  59.  
  60.     if (t1 == NULL || t2 == NULL)
  61.     return 0;
  62.  
  63.     l1 = TrkLen(t1);
  64.     l2 = TrkLen(t2);
  65.  
  66.     if (l1 != l2)
  67.     return 0;
  68.  
  69.      return (MyCmp(t1, t2, l1));
  70. }
  71.  
  72.  
  73.  
  74. void ReplaceTrack(UNIMOD * mf, int t1, int t2)
  75. {
  76.      int t;
  77.  
  78.      for (t = 0; t < mf->numpat * mf->numchn; t++) {
  79.     if (mf->patterns[t] == t1)
  80.          mf->patterns[t] = t2;
  81.      }
  82. }
  83.  
  84.  
  85.  
  86. void Optimize(UNIMOD * mf)
  87. /*
  88.     Optimizes the number of tracks in a modfile by removing tracks with
  89.     identical contents.
  90.  */
  91. {
  92.     int t, u, done = 0, same, newcnt = 0;
  93.      UBYTE *ta;
  94.      UBYTE **newtrk;
  95.  
  96.          if (!(newtrk = (UBYTE **)malloc(mf->numtrk * sizeof(UBYTE *))))
  97.     return;
  98.  
  99.      for (t = 0; t < mf->numtrk; t++) {
  100.  
  101.     /* ta is track to examine */
  102.  
  103.     ta = mf->tracks[t];
  104.  
  105.     /* does ta look familiar ? */
  106.  
  107.     for (same = u = 0; u < newcnt; u++) {
  108.          if (TrkCmp(ta, newtrk[u])) {
  109.         same = 1;
  110.         break;
  111.          }
  112.     }
  113.  
  114.     if (same) {
  115.          ReplaceTrack(mf, t, u);
  116.          done++;
  117.     } else {
  118.          ReplaceTrack(mf, t, newcnt);
  119.         newtrk[newcnt++] = ta;
  120.     }
  121.  
  122.     printf("\rOptimizing: %d\%", (t * 100L) / mf->numtrk);
  123.     }
  124.  
  125.     printf("\rOptimized : %d tracks\n", done);
  126.  
  127.     free(mf->tracks);
  128.     mf->tracks = newtrk;
  129.     mf->numtrk = newcnt;
  130. }
  131.  
  132. /***************************************************************************
  133. ****************************************************************************
  134. ***************************************************************************/
  135.  
  136.  
  137. SWORD MD_SampleLoad(FILE * fp, ULONG length, ULONG loopstart, ULONG loopend, UWORD flags)
  138. {
  139.      /* record position of sample */
  140.  
  141.     samplepos[numsamples] = ftell(fp);
  142.  
  143.      /* determine it's bytesize */
  144.  
  145.      if (flags & SF_16BITS)
  146.     length <<= 1;
  147.  
  148.      /* record bytesize and skip the sample */
  149.  
  150.      samplesize[numsamples++] = length;
  151.      fseek(fp, length, SEEK_CUR);
  152.      return 1;
  153. }
  154.  
  155.  
  156. void MD_SampleUnLoad(SWORD handle)
  157. {
  158. }
  159.  
  160.  
  161. void StrWrite(char *s)
  162. /*
  163.     Writes a null-terminated string as a pascal string to fpo.
  164.  */
  165. {
  166.      UWORD len;
  167.  
  168.      len = (s != NULL) ? strlen(s) : 0;
  169.      _mm_write_I_UWORD(len, fpo);
  170.      if (len)
  171.     fwrite(s, len, 1, fpo);
  172. }
  173.  
  174.  
  175. void TrkWrite(UBYTE * t)
  176. /*
  177.     Writes a track to fpo.
  178.  */
  179. {
  180.      UWORD len;
  181.      if (t == NULL)
  182.     printf("NULL track");
  183.      len = TrkLen(t);
  184.     _mm_write_I_UWORD(len, fpo);
  185.      fwrite(t, len, 1, fpo);
  186. }
  187.  
  188.  
  189.  
  190. char *stripname(char *path, char *ext)
  191. /*
  192.     Strips the filename from a path, and replaces or adds
  193.     a new extension to it.
  194. */
  195. {
  196.     char *n, *m;
  197.     static char newname[256];
  198.  
  199.     /* extract the filename from the path */
  200.  
  201. #ifdef unix
  202.     n = ((n = strrchr(path, '/')) == NULL) ? path : n + 1;
  203. #else
  204.     n = ((n = strrchr(path, '\\')) == NULL) ? path : n + 1;
  205.     if(m = strrchr(n, ':')) n=m+1;
  206. #endif
  207.  
  208.     /* copy the filename into 'newname' */
  209.     strncpy(newname,n,255);
  210.     newname[255]=0;
  211.  
  212.     /* remove the extension */
  213.     if (n = strrchr(newname, '.'))
  214.     *n = 0;
  215.  
  216.     /* and tack on the new extension */
  217.     return strcat(newname, ext);
  218. }
  219.  
  220.  
  221. int main(int argc, char *argv[])
  222. {
  223.     int t, v, w;
  224.     char *outname;
  225.  
  226.     puts(mikbanner);
  227.  
  228.     /* Expand wildcards on commandline (NoT on unix systems please): */
  229.  
  230. #ifndef unix
  231.     MyGlob(&argc, &argv, 0);
  232. #endif
  233.  
  234.     /*
  235.         Register the loaders we want to use..
  236.     */
  237.  
  238.     ML_RegisterLoader(&load_m15);
  239.     ML_RegisterLoader(&load_mod);
  240.     ML_RegisterLoader(&load_mtm);
  241.     ML_RegisterLoader(&load_s3m);
  242.     ML_RegisterLoader(&load_stm);
  243.     ML_RegisterLoader(&load_ult);
  244.     ML_RegisterLoader(&load_uni);
  245.     ML_RegisterLoader(&load_xm);
  246.  
  247.     if (argc < 2) {
  248.  
  249.         /* display a usage message */
  250.  
  251.         puts("Usage: MIKCVT <fletch.mod> ... ");
  252.         puts("Converts your modules to .UNI modules\n");
  253.         exit(-1);
  254.     }
  255.  
  256.     for (t = 1; t < argc; t++) {
  257.  
  258.         UNIMOD *mf;
  259.  
  260.         printf("In file : %s\n", argv[t]);
  261.  
  262.         numsamples = 0;
  263.  
  264.         if ((fpi = fopen(argv[t], "rb")) == NULL) {
  265.             printf("MikCvt Error: Error opening input file\n");
  266.             break;
  267.         }
  268.         outname = stripname(argv[t], ".uni");
  269.  
  270.         printf("Out file: %s\n", outname);
  271.  
  272.         if ((fpo = fopen(outname, "wb")) == NULL) {
  273.             printf("MikCvt Error: Error opening output file\n");
  274.             break;
  275.         }
  276.         mf = ML_LoadFP(fpi);
  277.  
  278.         /*      didn't work -> exit with error */
  279.  
  280.         if (mf == NULL) {
  281.             printf("MikCvt Error: %s\n", myerr);
  282.             fclose(fpi);
  283.             break;
  284.         }
  285.         printf("Songname: %s\n"
  286.                 "Modtype : %s\n",
  287.                 mf->songname,
  288.                 mf->modtype);
  289.  
  290.         /* Optimize the tracks */
  291.  
  292.         Optimize(mf);
  293.  
  294.         /* Write UNI header */
  295.  
  296.         fwrite("UN05", 4, 1, fpo);
  297.         _mm_write_UBYTE(mf->numchn, fpo);
  298.         _mm_write_I_UWORD(mf->numpos, fpo);
  299.         _mm_write_I_UWORD(mf->reppos, fpo);
  300.         _mm_write_I_UWORD(mf->numpat, fpo);
  301.         _mm_write_I_UWORD(mf->numtrk, fpo);
  302.         _mm_write_I_UWORD(mf->numins, fpo);
  303.         _mm_write_UBYTE(mf->initspeed, fpo);
  304.         _mm_write_UBYTE(mf->inittempo, fpo);
  305.         _mm_write_UBYTES(mf->positions, 256, fpo);
  306.         _mm_write_UBYTES(mf->panning, 32, fpo);
  307.         _mm_write_UBYTE(mf->flags, fpo);
  308.  
  309.         StrWrite(mf->songname);
  310.         StrWrite(mf->modtype);
  311.         StrWrite(mf->comment);
  312.  
  313.         /* Write instruments */
  314.  
  315.         for (v = 0; v < mf->numins; v++) {
  316.  
  317.             INSTRUMENT *i = &mf->instruments[v];
  318.  
  319.             _mm_write_UBYTE(i->numsmp, fpo);
  320.             _mm_write_UBYTES(i->samplenumber, 96, fpo);
  321.  
  322.             _mm_write_UBYTE(i->volflg, fpo);
  323.             _mm_write_UBYTE(i->volpts, fpo);
  324.             _mm_write_UBYTE(i->volsus, fpo);
  325.             _mm_write_UBYTE(i->volbeg, fpo);
  326.             _mm_write_UBYTE(i->volend, fpo);
  327.  
  328.             for (w = 0; w < 12; w++) {
  329.                 _mm_write_I_SWORD(i->volenv[w].pos, fpo);
  330.                 _mm_write_I_SWORD(i->volenv[w].val, fpo);
  331.             }
  332.  
  333.             _mm_write_UBYTE(i->panflg, fpo);
  334.             _mm_write_UBYTE(i->panpts, fpo);
  335.             _mm_write_UBYTE(i->pansus, fpo);
  336.             _mm_write_UBYTE(i->panbeg, fpo);
  337.             _mm_write_UBYTE(i->panend, fpo);
  338.  
  339.             for (w = 0; w < 12; w++) {
  340.                 _mm_write_I_SWORD(i->panenv[w].pos, fpo);
  341.                 _mm_write_I_SWORD(i->panenv[w].val, fpo);
  342.             }
  343.  
  344.             _mm_write_UBYTE(i->vibtype, fpo);
  345.             _mm_write_UBYTE(i->vibsweep, fpo);
  346.             _mm_write_UBYTE(i->vibdepth, fpo);
  347.             _mm_write_UBYTE(i->vibrate, fpo);
  348.             _mm_write_I_UWORD(i->volfade, fpo);
  349.  
  350.             StrWrite(i->insname);
  351.  
  352.             for (w = 0; w < i->numsmp; w++) {
  353.                 SAMPLE *s = &i->samples[w];
  354.  
  355.                 _mm_write_I_UWORD(s->c2spd, fpo);
  356.                 _mm_write_SBYTE(s->transpose, fpo);
  357.                 _mm_write_UBYTE(s->volume, fpo);
  358.                 _mm_write_UBYTE(s->panning, fpo);
  359.                 _mm_write_I_ULONG(s->length, fpo);
  360.                 _mm_write_I_ULONG(s->loopstart, fpo);
  361.                 _mm_write_I_ULONG(s->loopend, fpo);
  362.                 _mm_write_I_UWORD(s->flags, fpo);
  363.                 StrWrite(s->samplename);
  364.             }
  365.         }
  366.  
  367.         /* Write patterns */
  368.  
  369.         _mm_write_I_UWORDS(mf->pattrows, mf->numpat, fpo);
  370.         _mm_write_I_UWORDS(mf->patterns, mf->numpat * mf->numchn, fpo);
  371.  
  372.         /* Write tracks */
  373.  
  374.         for (v = 0; v < mf->numtrk; v++) {
  375.             TrkWrite(mf->tracks[v]);
  376.         }
  377.  
  378.         printf("Writing samples.. ");
  379.  
  380.         /* Write sample-data */
  381.  
  382.         for (v = 0; v < numsamples; v++) {
  383.              fseek(fpi, samplepos[v], SEEK_SET);
  384.              CopyData(fpi, fpo, samplesize[v]);
  385.         }
  386.  
  387.         puts("Done.");
  388.  
  389.         /* and clean up */
  390.  
  391.         fclose(fpo);
  392.         fclose(fpi);
  393.         ML_Free(mf);
  394.     }
  395.     return 0;
  396. }
  397.  
  398.